<?php


namespace wchat\qq;

use Kiri\Client;
use wchat\common\Help;
use wchat\common\Result;

class Redhat extends SmallProgram
{

    private string $charset      = 'UTF8';
    private string $sign         = '';
    private string $mch_billno   = '';
    private string $mch_name     = '';
    private string $re_openid    = '';
    private string $total_amount = '';
    private string $total_num    = '';
    private string $wishing      = '';
    private string $act_name     = '';
    private string $icon_id      = '';
    private string $banner_id    = '';
    private string $not_send_msg = '';
    private string $min_value    = '';
    private string $max_value    = '';


    private string $sendUrl   = '/cgi-bin/hongbao/qpay_hb_mch_send.cgi';
    private string $searchUrl = '/cgi-bin/mch_query/qpay_hb_mch_list_query.cgi';

    /**
     * @return string
     */
    public function getCharset(): string
    {
        return $this->charset;
    }

    /**
     * @param string $charset
     */
    public function setCharset(string $charset): void
    {
        $this->charset = $charset;
    }

    /**
     * @return string
     */
    public function getSign(): string
    {
        return $this->sign;
    }

    /**
     * @param string $sign
     */
    public function setSign(string $sign): void
    {
        $this->sign = $sign;
    }

    /**
     * @return string
     */
    public function getMchBillno(): string
    {
        return $this->mch_billno;
    }

    /**
     * @param string $mch_billno
     */
    public function setMchBillno(string $mch_billno): void
    {
        $this->mch_billno = $mch_billno;
    }

    /**
     * @return string
     */
    public function getMchName(): string
    {
        return $this->mch_name;
    }

    /**
     * @param string $mch_name
     */
    public function setMchName(string $mch_name): void
    {
        $this->mch_name = $mch_name;
    }


    /**
     * @return string
     */
    public function getReOpenid(): string
    {
        return $this->re_openid;
    }

    /**
     * @param string $re_openid
     */
    public function setReOpenid(string $re_openid): void
    {
        $this->re_openid = $re_openid;
    }

    /**
     * @return string
     */
    public function getTotalAmount(): string
    {
        return $this->total_amount;
    }

    /**
     * @param string $total_amount
     */
    public function setTotalAmount(string $total_amount): void
    {
        $this->total_amount = $total_amount;
    }

    /**
     * @return string
     */
    public function getTotalNum(): string
    {
        return $this->total_num;
    }

    /**
     * @param string $total_num
     */
    public function setTotalNum(string $total_num): void
    {
        $this->total_num = $total_num;
    }

    /**
     * @return string
     */
    public function getWishing(): string
    {
        return $this->wishing;
    }

    /**
     * @param string $wishing
     */
    public function setWishing(string $wishing): void
    {
        $this->wishing = $wishing;
    }

    /**
     * @return string
     */
    public function getActName(): string
    {
        return $this->act_name;
    }

    /**
     * @param string $act_name
     */
    public function setActName(string $act_name): void
    {
        $this->act_name = $act_name;
    }

    /**
     * @return string
     */
    public function getIconId(): string
    {
        return $this->icon_id;
    }

    /**
     * @param string $icon_id
     */
    public function setIconId(string $icon_id): void
    {
        $this->icon_id = $icon_id;
    }

    /**
     * @return string
     */
    public function getBannerId(): string
    {
        return $this->banner_id;
    }

    /**
     * @param string $banner_id
     */
    public function setBannerId(string $banner_id): void
    {
        $this->banner_id = $banner_id;
    }

    /**
     * @return string
     */
    public function getNotSendMsg(): string
    {
        return $this->not_send_msg;
    }

    /**
     * @param string $not_send_msg
     */
    public function setNotSendMsg(string $not_send_msg): void
    {
        $this->not_send_msg = $not_send_msg;
    }

    /**
     * @return string
     */
    public function getMinValue(): string
    {
        return $this->min_value;
    }

    /**
     * @param string $min_value
     */
    public function setMinValue(string $min_value): void
    {
        $this->min_value = $min_value;
    }

    /**
     * @return string
     */
    public function getMaxValue(): string
    {
        return $this->max_value;
    }

    /**
     * @param string $max_value
     */
    public function setMaxValue(string $max_value): void
    {
        $this->max_value = $max_value;
    }


    /**
     * @return mixed
     * 构建请求参数
     */
    public function generate(): array
    {
        $requestParam                 = [];
        $requestParam['charset']      = $this->getCharset();
        $requestParam['nonce_str']    = Help::random(30);
        $requestParam['mch_billno']   = $this->getMchBillno();
        $requestParam['mch_id']       = $this->payConfig->pay->qq->mchId;
        $requestParam['mch_name']     = $this->getMchName();
        $requestParam['qqappid']      = $this->payConfig->appId;
        $requestParam['re_openid']    = $this->getReOpenid();
        $requestParam['total_amount'] = $this->getTotalAmount() * 100;
        $requestParam['min_value']    = $this->getMinValue() * 100;
        $requestParam['max_value']    = $this->getMaxValue() * 100;
        $requestParam['total_num']    = $this->getTotalNum();
        $requestParam['wishing']      = $this->getWishing();
        $requestParam['act_name']     = $this->getActName();
        $requestParam['icon_id']      = $this->getIconId();
        $requestParam['notify_url']   = $this->payConfig->getNotifyUrl();
        $requestParam['sign']         = $this->builderSign($requestParam);

        return $requestParam;
    }


    /**
     * @param array $requestParam
     * @return string
     */
    private function builderSign(array $requestParam): string
    {
        return Help::sign($requestParam, $this->payConfig->pay->qq->mchSecret, $this->payConfig->getSignType());
    }

    /**
     * @return Result
     */
    public function redEnvelopes(): Result
    {
        $client = new Client('api.qpay.qq.com', 443, true);
        $client->withHeader(['Content-Type' => 'application/x-www-form-urlencoded']);
        $client->withSslKeyFile($this->payConfig->pay->qq->mchKey);
        $client->withSslCertFile($this->payConfig->pay->qq->mchCert);
        $client->withCa($this->payConfig->pay->qq->mchCa);
        $proxyHost = $this->payConfig->getProxyHost();
        $proxyPort = $this->payConfig->getProxyPort();
        if (!empty($proxyHost) && $proxyPort > 0) {
            $client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
        }
        $client->post($this->sendUrl, http_build_query($this->generate()));
        $client->close();
        if (!in_array($client->getStatusCode(), [101, 200, 201])) {
            return new Result(code: 505, message: $client->getBody());
        }
        $json = json_decode($client->getBody(), true);
        if (isset($json['return_code']) && $json['return_code'] != 'SUCCESS') {
            return new Result(code: 500, message: $json['return_msg'] ?? $json['retmsg']);
        }
        if ($json['retcode'] != 0) {
            return new Result(code: $json['retcode'], message: $json['retmsg']);
        } else {
            return new Result(code: 0, data: $json);
        }
    }


    /**
     * @param string $listid
     * @param string|null $orderNo
     * @return Result
     */
    public function searchByOrderNo(string $listid, ?string $orderNo = null): Result
    {
        $requestParam['nonce_str'] = Help::random(31);
        $requestParam['mch_id']    = $this->payConfig->pay->qq->mchId;
        $requestParam['listid']    = $listid;
        if (!empty($orderNo)) {
            $requestParam['mch_billno'] = $orderNo;
        }
        $requestParam['sign'] = $this->builderSign($requestParam);
        $client               = new Client('qpay.qq.com', 443, true);
        $proxyHost            = $this->payConfig->getProxyHost();
        $proxyPort            = $this->payConfig->getProxyPort();
        if (!empty($proxyHost) && $proxyPort > 0) {
            $client->withProxyHost($proxyHost)->withProxyPort($proxyPort);
        }
        $client->withHeader(['Content-Type' => 'application/json']);
        $client->post($this->searchUrl, $requestParam);
        $client->close();
        if (!in_array($client->getStatusCode(), [101, 200, 201])) {
            return new Result(code: 505, message: $client->getBody());
        }
        $json = json_decode($client->getBody(), true);
        if (isset($json['result']) && $json['result'] != 'SUCCESS') {
            return new Result(code: 500, message: $response['res_info'] ?? '订单查询失败!');
        } else {
            return new Result(code: 0, data: $json);
        }
    }

}
